home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
snap
/
atie.c
next >
Wrap
C/C++ Source or Header
|
1995-09-04
|
8KB
|
368 lines
/* atie.c -- Ascii To Input Event */
/* The contents of this file are copyright 1990, Mikael Karlsson.
* You may use these routines freely in non-commerical programs,
* provided that some notice of it's use is given in the program
* and/or documentation.
*/
struct HalfMap
{
UBYTE *KeyMapTypes;
ULONG *KeyMap;
UBYTE *Capsable;
UBYTE *Repeatable;
};
struct DeadSpec
{
UBYTE ds_Prev1DownCode;
UBYTE ds_Prev1DownQual;
UBYTE ds_Prev2DownCode;
UBYTE ds_Prev2DownQual;
};
#define CONTROLBITS ( ( 1 << 5) | ( 1 << 6))
#define KEYMAPSIZE 64
#define S IEQUALIFIER_LSHIFT
#define A IEQUALIFIER_LALT
#define C IEQUALIFIER_CONTROL
/* These tables can be found in RKM Libraries & Devices 1.3 */
WORD deadQuals[ 8][ 10] =
{
{KC_NOQUAL, 1, 0},
{KCF_SHIFT, 2, 0, S},
{KCF_ALT, 2, 0, A},
{KCF_ALT + KCF_SHIFT, 4, 0, S, A, S + A},
{KCF_CONTROL, 2, 0, C},
{KCF_CONTROL + KCF_SHIFT, 4, 0, S, C, S + C},
{KCF_CONTROL + KCF_ALT, 4, 0, A, C, A + C},
{KCF_CONTROL + KCF_ALT + KCF_SHIFT, 8, 0, S, A, S + A, C, C + S, C + A, C + S + A}
};
WORD normalQuals[ 8][ 6] =
{
{KC_NOQUAL, 1, 0, 0, 0, 0},
{KCF_SHIFT, 2, 0, 0, S, 0},
{KCF_ALT, 2, 0, 0, A, 0},
{KCF_ALT + KCF_SHIFT, 4, S + A, A, S, 0},
{KCF_CONTROL, 2, 0, 0, C, 0},
{KCF_CONTROL + KCF_SHIFT, 4, C + S, C, S, 0},
{KCF_CONTROL + KCF_ALT, 4, C + A, C, A, 0},
{KCF_CONTROL + KCF_ALT + KCF_SHIFT, 4, S + A, A, S, 0}
};
#define keytype 0
#define combos 1
#undef S
#undef A
#undef C
STATIC WORD checkNormalQual( LONG *four_bytesp, UBYTE val, UWORD type, UWORD *qualp)
{
register UBYTE *p = ( UBYTE *) four_bytesp; /* codes held in long word */
register WORD position;
register WORD i = normalQuals[ type][ combos];
position = 4;
while ( i--)
{
--position;
if ( p[ position] == val)
{
*qualp = normalQuals[ type][ position + 2];
return 1;
}
}
return 0;
}
WORD checkNormal( UBYTE *p, UBYTE val, WORD type, UWORD *qualp)
{
/* only one way to match a vanilla control key */
if ( type == KC_VANILLA && ( val & CONTROLBITS) == NULL)
{ /* control vanilla */
if ( checkNormalQual(
( LONG *)p,
val | CONTROLBITS,
type, qualp))
{
*qualp |= IEQUALIFIER_CONTROL;
return ( 1);
}
else
{
return ( 0);
}
}
else
{ /* not a control */
return ( checkNormalQual( (LONG *)p, val, type, qualp));
}
}
STATIC WORD checkDead( UBYTE *keybase, UBYTE val, WORD type, UWORD *qualp, ULONG *indexp)
{
WORD i;
WORD j;
register UBYTE *p = keybase; /* need to remember keybase for offsets */
UBYTE *deadp;
/* walk through two-byte entries, one for each qual. combo. */
for ( i = 0; i < deadQuals[ type][ combos]; ++i, p += 2)
{
switch ( p[ 0])
{
case DPF_DEAD: /* dead keys do not themselves map to anything */
break;
case DPF_MOD: /* dead key modifiable */
deadp = keybase + p[ 1];
/* look down the string indexed by dead-key index */
for ( j = 0; j < 6; ++j)
{
if ( deadp[ j] == val)
{
*qualp = deadQuals[ type][ i + 2];
*indexp = j;
return 1;
}
}
break;
case 0: /* normal stroke for this key */
if ( p[ 1] == val)
{
*qualp = deadQuals[ type][ i + 2];
return 1;
}
}
}
return ( 0);
}
/*
* Calculates Code+Qual of previous dead key ( should be keys)
* and puts them in DeapSpec.
* returns success ( 1) or failure ( 0).
*/
STATIC WORD BuildDeadSpec( ULONG inx, struct HalfMap *hm, WORD hms, struct DeadSpec *ds)
{
/* find keystroke which generates index */
register WORD code = 0;
register UBYTE *deadthing;
register WORD i;
do
{
/* check each deadkey in the table */
if ( hm->KeyMapTypes[ code] & KCF_DEAD)
{
register WORD type = hm->KeyMapTypes[ code] & 7;
/* keymap entry is pointer to prefix:byte pairs */
deadthing = ( UBYTE *) hm->KeyMap[ code];
for ( i = 0; i < deadQuals[ type][ combos]; ++i, deadthing += 2)
{
/* check for index prefix and correct index */
if ( deadthing[ 0] == DPF_DEAD &&
( deadthing[ 1] & DP_2DINDEXMASK) == inx)
{
ds->ds_Prev1DownCode = code;
ds->ds_Prev1DownQual = deadQuals[ type][ i + 2];
ds->ds_Prev2DownCode = 0;
ds->ds_Prev2DownQual = 0;
return 1;
}
}
}
}
while ( ++code < hms);
return 0; /* Not found */
}
STATIC WORD checkString( UBYTE *keybase, UBYTE val, WORD type, UWORD *qualp)
{
WORD i;
register UBYTE *p = keybase; /* need to remember keybase for offsets */
/* walk through two-byte entries, one for each qual. combo. */
for ( i = 0; i < deadQuals[ type][ combos]; ++i, p += 2)
{
if ( p[ 0] == 1)
{ /* One char in string */
if ( keybase[ p[ 1]] == val)
{ /* Our char? */
*qualp = deadQuals[ type][ i + 2];
return 1;
}
}
}
return ( 0);
}
/* BuildEvent tries to generate an input event.
* returns success ( 1) or failure ( 0).
*/
STATIC UWORD BuildEvent( register UBYTE value, struct HalfMap *hm, WORD hms, struct InputEvent *ie,
struct KeyMap *km) /* We need this to find dead prefix */
{
register UWORD code = 0;
register WORD type;
register LONG *p; /* points to four-byte lokeymap entry */
UWORD *qualp = &ie->ie_Qualifier;
WORD found_it = 0;
ULONG index = 0;
p = ( LONG *) hm->KeyMap;
do
{
type = hm->KeyMapTypes[ code];
/* determine type of key */
if ( type & KCF_STRING)
{
found_it = checkString( ( UBYTE *) * p, value, type & 7, qualp);
}
else if ( type & KCF_DEAD)
{
found_it = checkDead( ( UBYTE *) * p, value, type & 7, qualp, &index);
}
else if ( !( type & KCF_NOP))
{
found_it = checkNormal( ( UBYTE *)p, value, type & 7, qualp);
}
++p;
}
while ( !found_it && ++code < hms);
if ( found_it)
{
ie->ie_Code = code;
/* Successful BuildEvent. Check for dead key. */
if ( index)
{
struct HalfMap *dhm;
struct DeadSpec *ds = ( struct DeadSpec *)&ie->ie_EventAddress;
dhm = ( struct HalfMap *)&km->km_LoKeyMapTypes;
if ( BuildDeadSpec( index, dhm, 64, ds))
{
return 1;
}
dhm = ( struct HalfMap *)&km->km_HiKeyMapTypes;
if ( BuildDeadSpec( index, dhm, 56, ds))
{
return 1;
}
return 0; /* Couldn't find index generating dead key */
}
else
{
return 1;
}
}
else
{
return 0;
}
}
/*
* NAME
* AsciiToInputEvent -- build input event to generate ascii
*
* SYNOPSIS
* success = AsciiToInputEvent( ascii, inputevent, keymap)
* ULONG AsciiToInputEvent( ULONG, struct InputEvent *, struct KeyMap *)
*
* FUNCTION
* This function tries to generate an input event that, when sent
* to the input handler, will generate the specified ascii code.
*
* INPUTS
* ascii - the ascii code to be generated by the constructed
* input event.
*
* inputevent - the input event that will be filled will the
* appropriate values to generate the given ascii code.
*
* keymap - the keymap that the input event will be reverse-
* engineered from.
*
*
* RESULT
* success - a boolean value indicating whether the reverse-
* engineering was successful.
*
* NOTE
* The ascii code must be available in the given keymap to be
* generatable. Ascii values between 128 and 160 are usually
* not available with normal keymaps.
*
* SEE ALSO
* RawKeyConvert( ), V36 keymap.library/MapANSI( ).
*/
ULONG AsciiToInputEvent( ULONG ascii, register struct InputEvent *ie, struct KeyMap *km)
{
struct HalfMap *hm;
ie->ie_Class = IECLASS_RAWKEY;
ie->ie_Qualifier = 0;
ie->ie_EventAddress = 0;
/* Some ascii values has to be treated separately
since some programs know the difference between
for example CTRL-M and RETURN. */
{
WORD code = 0;
switch ( ascii)
{
case 0x08: /* backspace */
code = 0x41;
break;
case '\t': /* tab */
code = 0x42;
break;
case 0x0D: /* return */
code = 0x44;
break;
case 0x1B: /* esc */
code = 0x45;
break;
case 0x7F: /* del */
code = 0x46;
break;
}
if ( code)
{
ie->ie_Code = code;
return 1;
}
}
hm = ( struct HalfMap *)&km->km_LoKeyMapTypes;
if ( BuildEvent( ( UBYTE) ascii, hm, 64, ie, km))
{
return 1; /* Key found in LoKeyMap */
}
hm = ( struct HalfMap *)&km->km_HiKeyMapTypes;
if ( BuildEvent( ( UBYTE) ascii, hm, 56, ie, km))
{
ie->ie_Code += 64; /* Don't forget that we're in the hi keymap */
return 1; /* Key found in HiKeyMap */
}
return 0; /* No luck */
}